#pragma once
#include <iostream>
#include <string>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "Common.hpp"

class InetAddr{
public:
	InetAddr(){}
	InetAddr(const struct sockaddr_in& addr):_addr(addr){
		SetAddr(_addr);
	}

	InetAddr(const std::string& ip, uint16_t port){
		// 清空结构体，设置协议族
		memset(&_addr, 0, sizeof(_addr));
		_addr.sin_family = AF_INET;

		// ip转换，点分十进制字符串转32位网络字节序
		inet_pton(AF_INET, ip.c_str(), &_addr.sin_addr);

		// 端口转换，主机字节序转网络字节序
		_addr.sin_port = htons(port);
	}

	InetAddr(uint16_t port){
		// 清空结构体，设置协议族
		memset(&_addr, 0, sizeof(_addr));
		_addr.sin_family = AF_INET;

		// ip转换，设置INADDR_ANY，即0.0.0.0
		_addr.sin_addr.s_addr = INADDR_ANY;

		// 端口转换，主机字节序转网络字节序
		_addr.sin_port = htons(port);
	}

	void SetAddr(const struct sockaddr_in& addr){
		this->_addr = addr;
		// 端口转换，网络字节序转主机字节序
		_port = ntohs(addr.sin_port);
		
		// ip转换，32位网络字节序转点分十进制字符串
		char ipbuffer[64];
		inet_ntop(AF_INET, &_addr.sin_addr, ipbuffer, sizeof(ipbuffer));
		_ip = ipbuffer;
	}

	const std::string Ip() const{
		return _ip;
	}

	const uint16_t Port() const{
		return _port;
	}

	bool operator==(const InetAddr& addr) const {
		return addr.Ip() == _ip && addr.Port() == _port;
	}

	struct sockaddr_in GetAddr() {
		return _addr;
	}

	struct sockaddr* GetAddrPtr(){
		return CHAGNGE_PTR(_addr);
	}

	const socklen_t AddrLen(){
		return sizeof(_addr);
	}

	std::string StringAddr(){
		return "[" + _ip + ":" + std::to_string(_port) + "]";
	}

private:
	struct sockaddr_in _addr;
	std::string _ip;
	uint16_t _port;
};